package com.jufanshare.myblog.service.article;

import com.jufanshare.myblog.common.util.BaiduUrlPost;
import com.jufanshare.myblog.common.util.IPUtil;
import com.jufanshare.myblog.dao.ArticleDao;
import com.jufanshare.myblog.entity.*;
import com.jufanshare.myblog.service.base.BaseServiceImpl;
import com.jufanshare.myblog.service.record.RecordService;
import com.jufanshare.myblog.service.typecolumn.TypeColumnService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.beetl.sql.core.SQLManager;
import org.beetl.sql.core.engine.PageQuery;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.util.HtmlUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 作用：
 * 作者：Tiddler
 * 时间：2019/1/23 20：03
 * 类名： FriendUrlServiceImpl
 **/
@Service
@CacheConfig(cacheNames = "article")
public class ArticleServiceImpl extends BaseServiceImpl<Article> implements ArticleService {
    private Log log= LogFactory.getLog(ArticleServiceImpl.class);
    @Autowired
    private SQLManager sqlManager;
    @Autowired
    private ArticleDao articleDao;
    @Autowired
    private RecordService recordService;
    @Autowired
    private TypeColumnService typeColumnService;
    @Transactional
    @CacheEvict(cacheNames = {"homeData","cachePageData"},allEntries = true)
    @Override
    public Article mineInsert(Article article) {
        article.setDefultValue();
        Document parse = Jsoup.parse(article.getContent());
        String content = HtmlUtils.htmlEscape(parse.text());
        if(content.length()>=300){
            content=content.substring(0,300);
        }
        article.setBrief(content);
        insertTemplate(article,true);
        final String BAIDU_SERVER = "http://data.zz.baidu.com/urls?site=www.jufanshare.com&token=DJv0Fcea7ARIAvI7";//网站的服务器连接
        String[] urls={"http://www.jufanshare.com/content/"+article.getId()+".html"};
        String post = BaiduUrlPost.Post(BAIDU_SERVER, urls);//新增文章百度收录
        //类型文章数+1
        TypeColumn typeColumn=new TypeColumn();
        typeColumn.setId(article.getTypeid());
        typeColumnService.articleNumberAdd(typeColumn);
        return article;
    }

    /**
     * 重写updateTemplateById方法，刷新缓存
     * @param article
     * @return
     */
    @CacheEvict(cacheNames = {"homeData","cachePageData"},allEntries = true)
    public int updateTemplateById(Article article){
        return super.updateTemplateById(article);//此处不使用super的话会出现以下异常【死循环或无限递归】
        //Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Handler dispatch failed; nested exception is java.lang.StackOverflowError] with root cause
        //java.lang.StackOverflowError: null
    }
    @Override
    public List<Article> findPosition() {
        return articleDao.findPosition();
    }

    @Override
    public List<Article> findAllId() {
        return articleDao.findAllId();
    }

    @Cacheable(cacheNames = "homeData")
    @Override
    public Map<String, Object> homeData() {
        Map<String,Object> resData=new HashMap<String, Object>();
        List<Article> carousel = sqlManager.query(Article.class).andEq("position", "首页轮播")
                .andEq("articleState","正常").orderBy("id desc").limit(1,5)
                .select();
        List<Article> threeModule = sqlManager.query(Article.class).andEq("position", "首页三模块")
                .andEq("articleState","正常").orderBy("id desc").limit(1, 3)
                .select();
        List<Article> originalFirst = sqlManager.query(Article.class).andEq("position", "原创首推")
                .andEq("articleState","正常").orderBy("id desc").limit(1, 1)
                .select();
        List<Article> bozhuTuijian = sqlManager.query(Article.class).andEq("position", "博主推荐")
                .andEq("articleState", "正常").orderBy("id desc").limit(1, 10)
                .select();
        List<Article> yuanChuang = sqlManager.query(Article.class).andEq("position", "默认").andEq("typeId", 21).andEq("articleState", "正常").orderBy("id desc")
                .limit(1, 10).select();

        List<Article> jishuArticle = sqlManager.query(Article.class).andEq("position", "默认").andEq("columnId", 9).andEq("articleState", "正常").orderBy("id desc")
                .limit(1, 10).select();
        List<Article> chengxuRenshengArticle = sqlManager.query(Article.class).andEq("position", "默认").andEq("columnId", 10).andEq("articleState", "正常").orderBy("id desc")
                .limit(1, 10).select();
        List<Article> lifeArticle = sqlManager.query(Article.class).andEq("position", "默认").andEq("columnId", 11).andEq("articleState", "正常").orderBy("id desc")
                .limit(1, 10).select();
        List<Article> toolArticle = sqlManager.query(Article.class).andEq("position", "默认").andEq("columnId", 12).andEq("articleState", "正常").orderBy("id desc")
                .limit(1, 10).select();
        //排行榜
        List<Article> rankingList = sqlManager.query(Article.class).andEq("position", "默认").andEq("articleState", "正常").orderBy("pvNumber desc")
                .limit(1, 10).select();
        //综合文章列表
        Article zonheArticle=new Article();
        zonheArticle.setArticlestate("正常");
        zonheArticle.setPosition("默认");
        PageQuery<Article> zonhePageQuery=new PageQuery<Article>();
        zonhePageQuery.setPageSize(15);
        zonhePageQuery.setOrderBy("id desc");
        PageQuery<Article> byPage = findByPage(zonheArticle, zonhePageQuery);

        List<FriendUrl> friendUrls = sqlManager.query(FriendUrl.class).select();

        List<Comment> commentList = sqlManager.query(Comment.class).orderBy("id desc").limit(1, 10).select();

        long pvnumber = sqlManager.query(Request.class).andIsNotNull("reqIp").groupBy("reqIp").count();
        long uvnumber = articleDao.uvnumber();
        long commentNumber = articleDao.commentNumber();
        long articleNumber = sqlManager.query(Article.class).andEq("articleState", "正常").count();

        resData.put("carouselList",carousel);
        resData.put("threeModuleList",threeModule);
        resData.put("originalFirstList",originalFirst);
        resData.put("bozhuTuijianList",bozhuTuijian);

        resData.put("yuanChuangList",yuanChuang);
        resData.put("jishuArticleList",jishuArticle);
        resData.put("chengxuRenshengArticleList",chengxuRenshengArticle);
        resData.put("lifeArticleList",lifeArticle);
        resData.put("toolArticleList",toolArticle);
        resData.put("rankingList",rankingList);
        resData.put("zonheList",byPage.getList());
        resData.put("friendUrlList",friendUrls);
        resData.put("commentList",commentList);

        resData.put("pvnumber",pvnumber);
        resData.put("uvnumber",uvnumber);
        resData.put("commentNumber",commentNumber);
        resData.put("articleNumber",articleNumber);

        return resData;
    }
    @Cacheable(cacheNames = "cachePageData")
    @Override
    public PageQuery<Article> cachePageData(int columnId, int typeId, int pageNum,String sort) {
        PageQuery<Article> pageQuery=new PageQuery<Article>();
        pageQuery.setPageSize(20);
        pageQuery.setPageNumber(pageNum);
        pageQuery.setOrderBy(sortJudge(sort));

        Article article=new Article();
        article.setArticlestate("正常");
        article.setColumnid(columnId);
        if(typeId!=0){
            article.setTypeid(typeId);
        }
        PageQuery<Article> byPage = findByPage(article, pageQuery);
        return byPage;
    }

    @CacheEvict(cacheNames = {"homeData","cachePageData"},allEntries = true)
    @Override
    public void flushArticleData() {
        log.debug("首页数据刷新成功");
    }

    @Override
    public List<Article> listByType(int typeId) {
        List<Article> select = sqlManager.query(Article.class).andEq("typeId", typeId).andEq("articleState", "正常").orderBy("pvNumber DESC")
                .limit(1, 10).select();
        return select;
    }
    @Async
    @Transactional
    @Override
    public void uvnumberAdd(int id, HttpServletRequest servletRequest) {
        Record record=new Record();
        record.setRecordtype("uvnumber_"+id+"_record");
        record.setRecordvalue(IPUtil.getIpAddr(servletRequest));
        long count = recordService.templateCount(record);
        if(count>=1){
            log.debug("当前IP已经记录");
        }else {
            record.setRecorddatetime(new Date());
            recordService.insert(record);
            Article article=new Article();
            article.setId(id);
            articleDao.uvnumberAdd(article);
        }
    }
    @Async
    @Transactional
    @Override
    public void pvnumberAdd(int id, HttpServletRequest servletRequest) {
        Record record=new Record();
        record.setRecordtype("pvnumber_"+id+"_record");
        record.setRecordvalue(IPUtil.getIpAddr(servletRequest));
        long count = recordService.templateCount(record);
        if(count>=1){
            log.debug("当前IP今日已经记录");
        }else {
            record.setRecorddatetime(new Date());
            recordService.insert(record);
            Article article=new Article();
            article.setId(id);
            articleDao.pvnumberAdd(article);
        }
    }

    //    当前类私有方法【排序判断】
    private String sortJudge(String sort){
        String result="id DESC";
        switch (sort){
            case "time":
                result="id DESC";
                break;
            case "visit":
                result="pvNumber DESC";
                break;
            case "comment":
                result="commentNumber DESC";
                break;
            default:
                break;
        }
        return result;
    }
}
